﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace BaiDuSitemap.Setting
{
    public partial class ucURL : UserControl
    {
        #region Attributes

        private Thread myThread = null;
        private delegate void myDeleGateInitComboBox(int index);
        private delegate string myDeleGategetComboBoxSelectValue();
        private delegate string myDeleGategetComboBoxSelectIndex();
        private delegate DataGridViewRowCollection myDeleGategetDataGridViewRows();
        private delegate void myDeleGateSetProgress(bool b, string s, int index, int count, int skip);
        private delegate void myDeleGateSetButton(bool b);

        private string txtFileName = "";

        #endregion

        #region ucURL

        public ucURL()
        {
            InitializeComponent();
            this.pProgress.BackColor = Color.FromArgb(5, 0, 0, 0);
        }

        private void ucURL_Load(object sender, EventArgs e)
        {
            InitComboBox(0);
        }

        private void ucURL_SizeChanged(object sender, EventArgs e)
        {
            this.picClose.Location = new Point(this.Width - this.picClose.Width - 3, 3);
            Point p = new Point();
            p.X = (this.Width - this.pProgress.Width) / 2;
            p.Y = (this.Height - this.pProgress.Height) / 2;
            this.pProgress.Location = p;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.statusStrip1.BackColor = Sitemap.AeroColor;
        }

        #endregion

        #region Event

        #region Button

        private void btnImport_Click(object sender, EventArgs e)
        {
            #region 确认操作

            if (!getStatus())
            {
                MessageBox.Show("请等待当前操作完成");
                return;
            }

            if (int.Parse(this.cbbGroup.SelectedValue.ToString()) <= 0)
            {
                MessageBox.Show("请选择需要导入的分组");
                return;
            }

            if (MessageBox.Show("请确认要导入网址到分组 " + this.cbbGroup.GetItemText(this.cbbGroup.SelectedItem) + " 吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
            {
                return;
            }

            bool IsClear = false;
            DialogResult Result = DialogResult.OK;
            if (this.dgvURL.Rows.Count > 0) Result = MessageBox.Show("是否清空现有网址数据?", "系统提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            switch (Result)
            {
                case DialogResult.Cancel:
                    return;
                case DialogResult.Yes:
                    IsClear = true;
                    break;
                default:
                    IsClear = false;
                    break;
            }

            #endregion

            #region 选择导入文件

            OpenFileDialog myOpenFileDialog = new OpenFileDialog();
            try
            {
                myOpenFileDialog.Title = "请选择包含网址的文本文件";
                myOpenFileDialog.Filter = "text file (*.txt;*.log)|*.txt;*.log|AllFiles (*.*)|*.*";
                if (DialogResult.Cancel == myOpenFileDialog.ShowDialog())
                {
                    return;
                }

                txtFileName = myOpenFileDialog.FileName;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                myOpenFileDialog.Dispose();
            }

            #endregion

            #region 清除旧数据

            if (IsClear)
            {
                DBO.URL.DeleteByGroup(int.Parse(this.cbbGroup.SelectedValue.ToString()));
                InitComboBox(int.Parse(this.cbbGroup.SelectedValue.ToString()));
            }

            #endregion

            myThread = new Thread(new ThreadStart(ThreadImport));
            myThread.Start();
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            if (!getStatus())
            {
                MessageBox.Show("请等待当前操作完成");
                return;
            }

            SaveFileDialog sfDialog = new SaveFileDialog();
            try
            {
                sfDialog.ValidateNames = true;
                sfDialog.Filter = "文本文件(*.txt)|*.txt";
                sfDialog.FilterIndex = 1;
                sfDialog.DefaultExt = "txt";
                sfDialog.FileName = "";
                sfDialog.AddExtension = true;
                if (sfDialog.ShowDialog() == DialogResult.Cancel)
                {
                    return;
                }

                txtFileName = sfDialog.FileName;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                sfDialog.Dispose();
            }

            myThread = new Thread(new ThreadStart(ThreadExport));
            myThread.Start();

        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (!getStatus())
            {
                MessageBox.Show("请等待当前操作完成");
                return;
            }

            URL myURL = new URL();
            try
            {
                myURL.myURL = this;
                myURL.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                myURL.Dispose();
            }
        }

        private void btnModify_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                MessageBox.Show("请等待当前操作完成");
                return;
            }

            if (this.dgvURL.SelectedRows.Count == 0)
            {
                MessageBox.Show("请选择要修改的数据项");
                return;
            }

            URL myURL = new URL();
            try
            {
                myURL.myURL = this;
                myURL.IsAdd = false;
                myURL.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                myURL.Dispose();
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            if (!getStatus())
            {
                MessageBox.Show("请等待当前操作完成");
                return;
            }

            if (this.dgvURL.RowCount == 0) return;
            if (MessageBox.Show("清除后不能恢复，请再次确认要清除分组 " + this.cbbGroup.GetItemText(this.cbbGroup.SelectedItem) + " 的所有网址吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.Cancel) return;

            int result = DBO.URL.DeleteByGroup(int.Parse(this.cbbGroup.SelectedValue.ToString()));
            switch (result)
            {
                case -1:
                    MessageBox.Show("操作失败");
                    return;
                default:
                    MessageBox.Show(string.Format("共删除{0}条记录", result));
                    break;
            }

            InitComboBox(this.cbbGroup.SelectedIndex);
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (!getStatus())
            {
                MessageBox.Show("请等待当前操作完成");
                return;
            }

            if (this.dgvURL.SelectedRows.Count == 0)
            {
                MessageBox.Show("请选择要删除的数据项");
                return;
            }

            List<string> urls = new List<string>();
            foreach (DataGridViewRow row in this.dgvURL.SelectedRows)
            {
                urls.Add(row.Cells[0].Value.ToString());
            }

            int result = DBO.URL.Delete(urls);
            if (result == -1)
            {
                MessageBox.Show("操作失败");
                return;
            }
            else
            {
                MessageBox.Show(string.Format("共删除{0}条记录", result));
            }

            InitComboBox(this.cbbGroup.SelectedIndex);
        }

        private void btnCheck404_Click(object sender, EventArgs e)
        {
            if (!getStatus())
            {
                MessageBox.Show("请等待当前操作完成");
                return;
            }

            SetButton(true);
            myThread = new Thread(new ThreadStart(ThreadCheck404));
            myThread.Start();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行404检查，确认要取消吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }
                myThread.Abort();
                SetButton(false);
                SetProgress(false, "", 0, 0, 0);
            }
        }

        #endregion

        #region Picture

        private void picClose_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行数据操作，确认要关闭吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }

                myThread.Abort();
            }

            this.Dispose();
        }

        private void picClose_MouseEnter(object sender, EventArgs e)
        {
            this.picClose.Image = Properties.Resources.close02;
        }

        private void picClose_MouseLeave(object sender, EventArgs e)
        {
            this.picClose.Image = Properties.Resources.close01;
        }

        #endregion

        #region ComboBox

        private void cbbGroup_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.cbbGroup.SelectedIndex == 0) return;

            DataTable dt = DBO.URL.get4Sitemap(int.Parse(this.cbbGroup.SelectedValue.ToString()));

            this.dgvURL.AutoGenerateColumns = false;
            this.dgvURL.Columns[0].DataPropertyName = "url";
            this.dgvURL.Columns[1].DataPropertyName = "gname";
            this.dgvURL.DataSource = dt;
        }

        #endregion

        #region Label

        public void lblRefresh_Click(object sender, EventArgs e)
        {
            if (!getStatus())
            {
                MessageBox.Show("请等待当前操作完成");
                return;
            }

            InitComboBox(this.cbbGroup.SelectedIndex);
        }

        private void lblRefresh_MouseHover(object sender, EventArgs e)
        {
            ((Label)sender).ForeColor = Color.Red;
        }

        private void lblRefresh_MouseLeave(object sender, EventArgs e)
        {
            ((Label)sender).ForeColor = Color.Blue;
        }

        #endregion

        #region DataGridView

        private void dgvURL_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            this.tsslMsg.Visible = true;
            this.tsslMsg.Text = string.Format("网址总数：{0}", this.dgvURL.RowCount);
        }

        private void dgvURL_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (e.RowIndex < 0) return;

                if (e.ColumnIndex == 0)
                {
                    if (MessageBox.Show("确认要打开该地址吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) return;

                    Process.Start(this.dgvURL.Rows[e.RowIndex].Cells[0].Value.ToString());
                }
            }
        }

        #endregion

        #endregion

        #region Thread

        private void ThreadImport()
        {
            FileStream ifs = null;
            StreamReader sr = null;

            try
            {
                ifs = new FileStream(txtFileName, FileMode.Open, FileAccess.Read);
                sr = new StreamReader(ifs);

                int gid = int.Parse(getComboBoxSelectValue());
                int mySkip = 0;
                int lineIndex = 0;

                while (!sr.EndOfStream)
                {
                    SetProgress(true, "正在导入网址。已导入：{0}，跳过：{2}", lineIndex, 0, mySkip);
                    string inputStr = sr.ReadLine();
                    //写入数据库
                    if (DBO.URL.Add(inputStr, gid) != 1)
                    {
                        mySkip++;
                        continue;
                    }

                    lineIndex++;
                }
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                ifs.Dispose();
                SetProgress(false, "", 0, 0, 0);
                InitComboBox(int.Parse(getComboBoxSelectIndex()));
            }
        }

        private void ThreadExport()
        {
            string message = "导出成功";

            try
            {
                SetProgress(true, "正在导出网址，请稍后……", 0, 0, 0);
                Tools.Export.Export2Txt(this.dgvURL, txtFileName);
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                message = "导出失败，错误信息：" + ex.Message;
            }
            finally
            {
                SetProgress(false, "正在导出网址，请稍后……", 0, 0, 0);
                MessageBox.Show(message);
            }
        }

        private void ThreadCheck404()
        {
            bool b = false;

            DialogResult result = MessageBox.Show("是否立即清除返回状态为404的网页地址？", "操作确认", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            switch (result)
            {
                case DialogResult.Cancel:
                    return;
                case DialogResult.Yes:
                    b = true;
                    break;
                default:
                    b = false;
                    break;
            }

            int error = 0;
            try
            {
                DataGridViewRowCollection rows = getDataGridViewRows();
                string url = "";
                int index = 0;
                int count = rows.Count;
                foreach (DataGridViewRow row in rows)
                {
                    SetProgress(true, "正在进行404检查。已完成{0}/{1}", index, count, 0);
                    index++;

                    url = row.Cells[0].Value.ToString();

                    if (Tools.Gather.getStatusCode(url) != HttpStatusCode.NotFound) continue;
                    error++;

                    if (b) DBO.URL.Delete(url);
                    else row.DefaultCellStyle.ForeColor = Color.Red;
                }

            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                SetProgress(false, "", 0, 0, 0);
                MessageBox.Show(string.Format("共" + (b ? "清理" : "检查出") + "返回状态为404的地址{0}条", error));
                if(b) InitComboBox(int.Parse(getComboBoxSelectIndex()));
            }
        }

        #endregion

        #region Method

        private void InitComboBox(int index)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateInitComboBox(InitComboBox), new object[] { index });
            }
            else
            {
                DataTable dt = DBO.Group.getAll();
                DataRow dr = null;
                dr = dt.NewRow();
                dr["gid"] = "-1";
                dr["gname"] = "--请选择--";
                dt.Rows.InsertAt(dr, 0);
                dr = dt.NewRow();
                dr["gid"] = "0";
                dr["gname"] = "--全部--";
                dt.Rows.InsertAt(dr, 1);

                this.cbbGroup.ValueMember = "gid";
                this.cbbGroup.DisplayMember = "gname";
                this.cbbGroup.DataSource = dt;
                this.cbbGroup.SelectedIndex = dt.Rows.Count - 1 < index ? 0 : index;
            }
        }

        private string getComboBoxSelectValue()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetComboBoxSelectValue(getComboBoxSelectValue)) as string;
            }
            else
            {
                return this.cbbGroup.SelectedValue.ToString();
            }
        }

        private string getComboBoxSelectIndex()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetComboBoxSelectIndex(getComboBoxSelectIndex)) as string;
            }
            else
            {
                return this.cbbGroup.SelectedIndex.ToString();
            }
        }

        private DataGridViewRowCollection getDataGridViewRows()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetDataGridViewRows(getDataGridViewRows)) as DataGridViewRowCollection;
            }
            else
            {
                return this.dgvURL.Rows;
            }
        }

        private void SetProgress(bool b, string s, int index, int count, int skip)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateSetProgress(SetProgress), new object[] { b, s, index, count, skip });
            }
            else
            {
                if (count == 0)
                {
                    this.pbProgress.Style = ProgressBarStyle.Marquee;
                    this.lblMsg.Text = string.Format(s, index, count, skip);
                }
                else
                {
                    this.pbProgress.Style = ProgressBarStyle.Blocks;
                    this.pbProgress.Maximum = count;
                    this.pbProgress.Value = index;
                    this.lblMsg.Text = string.Format(s, index, count, skip);
                }
                this.pProgress.Visible = b;
                this.cbbGroup.Enabled = !b;
            }
        }

        private void SetButton(bool b)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateSetButton(SetButton));
            }
            else
            {
                this.btnCancel.Enabled = b;
            }
        }

        public bool Closing()
        {
            if (myThread != null && myThread.IsAlive) return false;
            return true;
        }

        private bool getStatus()
        {
            if ((myThread != null && myThread.IsAlive) || this.pProgress.Visible) return false;
            return true;
        }

        #endregion
    }
}
